package simulation;

import java.text.DecimalFormat;

/**
 * @author cwhalen
 * 
 */
public class Earth
{
	public int radius;
	public double circumference;
	private int gridSpacing;
	public Node grid[][];
	private int gridWidth;
	private int gridHeight;


	public Earth(int gridSpacing, int radius)
	{
		super();
		this.gridSpacing = gridSpacing;
		this.radius = radius;
		this.circumference = (2.0 * radius) * Math.PI;
		this.initGrid();
	}


	private void initGrid()
	{
		/*
		 * Create the grid that holds the node objects. This grid maps to the
		 * quadrants on the surface of the sphere
		 */
		this.gridWidth = (int) (360 / gridSpacing);
		this.gridHeight = (int) (180 / gridSpacing);

		System.out.println("Grid Dimensions: " + gridWidth + "," + gridHeight);

		this.grid = new Node[gridHeight][gridWidth];

		for (int y = 0; y < gridHeight; y++)
		{
			for (int x = 0; x < gridWidth; x++)
			{
				this.grid[y][x] = new Node();
				this.grid[y][x].degLatTop = 90 - (y * gridSpacing);
				this.grid[y][x].degLatBottom = 90 - ((y + 1) * gridSpacing);

				this.grid[y][x].degLonLeft = 180 - (x * gridSpacing);
				this.grid[y][x].degLonRight = 180 - ((x + 1) * gridSpacing);

				// Sets the length of the sides and height as well as the area
				// based on the radius of the earth
				this.grid[y][x].cGeometry(this.radius);
			}
		}
	}


	/**
	 * @param sun
	 */
	public void step(Sun sun)
	{
		for (int y = 0; y < gridHeight; y++)
		{
			for (int x = 0; x < gridWidth; x++)
			{
				if (y == 0) // North Edges
				{
					if (x == 0) // Northwest edge
					{
						this.grid[y][x].cTemp(grid[0][gridWidth - 1].oldTemp,
								grid[y][x + 1].oldTemp, 0,
								grid[y + 1][x].oldTemp, sun);
					} else if (x == gridWidth - 1) // Northeast edge
					{
						this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
								grid[y][0].oldTemp, 0, grid[y + 1][x].oldTemp,
								sun);
					} else
					// Middle North edges
					{
						this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
								grid[y][x + 1].oldTemp, 0,
								grid[y + 1][x].oldTemp, sun);
					}
				} else if (y == gridHeight - 1) // South Edges
				{
					if (x == 0) // Southwest edge
					{
						this.grid[y][x].cTemp(grid[y][gridWidth - 1].oldTemp,
								grid[y][x + 1].oldTemp, grid[y - 1][x].oldTemp,
								0, sun);
					} else if (x == gridWidth - 1) // Southeast edge
					{
						this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
								grid[y][0].oldTemp, grid[y - 1][x].oldTemp, 0,
								sun);
					} else
					// Middle South edges
					{
						this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
								grid[y][x + 1].oldTemp, grid[y - 1][x].oldTemp,
								0, sun);
					}
				} else if (x == 0 && (y != 0 || y != gridHeight - 1))
				// Western edges excluding the corner edges
				{
					this.grid[y][x].cTemp(grid[y][gridWidth - 1].oldTemp,
							grid[y][x + 1].oldTemp, grid[y - 1][x].oldTemp,
							grid[y + 1][x].oldTemp, sun);
				} else if (x == gridWidth - 1
						&& (y != 0 || y != gridHeight - 1))
				// Eastern edges excluding the corner edges
				{
					this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
							grid[y][0].oldTemp, grid[y - 1][x].oldTemp,
							grid[y + 1][x].oldTemp, sun);
				} else
				// Center edges
				{
					this.grid[y][x].cTemp(grid[y][x - 1].oldTemp,
							grid[y][x + 1].oldTemp, grid[y - 1][x].oldTemp,
							grid[y + 1][x].oldTemp, sun);
				}
			}
		}

		this.swap();
	}


	/**
	 * 
	 */
	public void swap()
	{
		for (int y = 0; y < gridHeight; y += 1)
		{
			for (int x = 0; x < gridWidth; x += 1)
			{
				this.grid[y][x].swapTemp();
			}
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	public String toString()
	{
		String result = "";
		for (int y = 0; y < gridHeight; y += 1)
		{
			for (int x = 0; x < gridWidth; x += 1)
			{
				result += "|"
						+ new DecimalFormat("0.00")
								.format(this.grid[y][x].newTemp) + "|";
			}
			result += "\n";
		}
		return result;
	}


	/**
	 * 
	 */
	public void print()
	{
		for (int y = 0; y < gridHeight; y += 1)
		{
			for (int x = 0; x < gridWidth; x += 1)
			{
				System.out.print("|"
						+ new DecimalFormat("0.00")
								.format(this.grid[y][x].oldTemp) + "|");

			}
			System.out.print("\n");
		}
	}


	/**
	 * @return
	 */
	public double totalTemp()
	{
		double result = 0;

		for (int y = 0; y < gridHeight; y += 1)
		{
			for (int x = 0; x < gridWidth; x += 1)
			{
				result += this.grid[y][x].oldTemp;
			}
		}

		return result;
	}
}
